package com.ms.service.module.zone.db;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Query;
import org.hibernate.Session;

import com.ms.game.common.GameType;
import com.ms.game.common.OSType;
import com.xpec.c4.db.basic.BasicGameDAO;
import com.xpec.c4.db.hibernate.manager.HibernateManager;

public class GameHallDAO extends BasicGameDAO
{
	private static final Log log = LogFactory.getLog(GameHallDAO.class);
	
	
	/**
	 * 讀取所有遊戲館資料
	 * @return
	 */
	public static List<GameHallConfigModel> getHallConfigList()
	{
		Session session  = HibernateManager.getSession();
		Query query = session.createQuery("from GameHallConfigModel");
		List<GameHallConfigModel> gameHallList = (List<GameHallConfigModel>)query.list();
		HibernateManager.endSession();
		return gameHallList;
	}
	
	/**
	 * 用dbid取得指定的遊戲館資料
	 */
	public static GameHallConfigModel getGameHallModelByDBID(String dbId){	
		Session session = HibernateManager.getSession();
		Query query = session.createQuery("from GameHallConfigModel Where db_id = :DBID");
		query.setParameter("DBID", dbId);
		GameHallConfigModel gameHallModel = (GameHallConfigModel)query.uniqueResult();
		HibernateManager.endSession();
		return gameHallModel;
	}
	
	public static boolean update(GameHallConfigModel model){
		Session session = HibernateManager.txBegin();
		session.update(model);
		return HibernateManager.txCommitFailRollbackClearSession();
	}
	
	/**
	 * 檢查與新增新的gameList
	 */
	public static void checkAndInsertNewGameTypeModel(){
		List<GameHallConfigModel> gamelist = getHallConfigList();
		
		HashMap<OSType, ArrayList<GameType>> gameCheckMap = new HashMap<OSType, ArrayList<GameType>>();
		HashMap<OSType, Integer> maxOrderNum = new HashMap<OSType, Integer>();
		for(GameHallConfigModel model : gamelist){

			OSType osType = model.getOsType();
			GameType gameType = null;
			
			try {
				gameType = GameType.valueOf(model.getGameType());
			} catch (Exception e) {
				if(log.isErrorEnabled()){
					log.error("GameHallConfigModel can't cast gameType by "+model.getGameType()+" at dbid:"+model.getDb_id());
				}
				continue;
			}
			
			if(osType == null){
				if(log.isErrorEnabled()){
					log.error("GameHallConfigModel has null osType at dbid:"+model.getDb_id());
				}
				continue;
			}
			
			ArrayList<GameType> list = gameCheckMap.get(osType);
			if(list == null){
				list = new ArrayList<GameType>();
				gameCheckMap.put(osType, list);
			}
			
			if(!list.contains(gameType)){
				list.add(gameType);	
			}
			else{
				if(log.isErrorEnabled()){
					log.error("duplicated GameType :"+gameType+" in osType:"+osType);
				}
			}
			
			int orderNum = model.getOrderNum();
			int maxNum = (maxOrderNum.containsKey(osType)) ? maxOrderNum.get(osType) : Integer.MIN_VALUE;
			if(maxNum < orderNum){
				maxOrderNum.put(osType, orderNum);
			}
			
		}
		
		//要新增進DB的新models
		ArrayList<GameHallConfigModel> newModels = new ArrayList<GameHallConfigModel>();
		
		//每一種OS類型
		for(OSType osType : OSType.values()){
			ArrayList<GameType> list = gameCheckMap.get(osType);
			if(list == null){
				//這裡可能是DB內完全沒這個OS的資料
				list = new ArrayList<GameType>();
				gameCheckMap.put(osType, list);
			}
			
			//當前OS最大順序
			int currentMaxOrderNum = (maxOrderNum.containsKey(osType)) ? maxOrderNum.get(osType) : 0;
			
			//每一種遊戲類型
			for(GameType gameType : GameType.values()){
				if(!list.contains(gameType)){
					
					currentMaxOrderNum ++;
					
					GameHallConfigModel newOne = new GameHallConfigModel();
					newOne.setOsType(osType);
					newOne.setGameType(gameType.name());
					newOne.setAllowIpList("");
					newOne.setIcon(GameHallConfigModel.ICON_COMING_SOON);
					newOne.setOpen(false);//初始關閉
					newOne.setOpenTime(new Date());//先用新增的時間
					newOne.setTip(GameHallConfigModel.TIP_EMPTY);
					newOne.setOrderNum(currentMaxOrderNum);
					
					newModels.add(newOne);
				}
			}
		}
		
		if(newModels.size() > 0){
			Session session = HibernateManager.txBegin();
			
			for(GameHallConfigModel model : newModels){
				try {
					session.save(model);	
				} catch (Exception e) {
					if(log.isErrorEnabled()){
						log.error("save new GameHallConfigModel to DB fail, osType:"+model.getOsType()+", gameType:"+model.getGameType());
					}
				}
				continue;
			}
			
			HibernateManager.txCommitFailRollbackClearSession();
		}
	}
	
	/**
	 * 重新排序gameList
	 */
	public static String sortGameOrder(OSType osType, String[] gameOrder){
		if(osType == null){
			return "osType is null";
		}
		
		if(gameOrder == null || gameOrder.length != GameType.values().length){
			return "gameOrder size is not correct";
		}
		
		//讀取該OS的所有遊戲
		Session session  = HibernateManager.getSession();
		Query query = session.createQuery("from GameHallConfigModel where osType = :OS");
		query.setParameter("OS", osType);
		List<GameHallConfigModel> gamelist = (List<GameHallConfigModel>)query.list();
		HibernateManager.endSession();
		
		//如果是空的
		if(gamelist.size() == 0){
			return "gameList is empty by osType:"+osType.name();
		}
		
		//修正完順序的modelSize檢查
		Set<String> doubleCheck = new HashSet<String>();
		
		for(int order = 0; order < gameOrder.length; order++){
			
			String gameType = gameOrder[order];
			
			if(doubleCheck.contains(gameType)){
				continue;
			}
			
			for(GameHallConfigModel model : gamelist){
				if(gameType.equals(model.getGameType())){
					model.setOrderNum(order);
					doubleCheck.add(gameType);
					break;
				}
			}
		}
		
		//重新排序完的size應該要一模一樣
		if(doubleCheck.size() != gamelist.size()){
			return "new gameList size can't match the ordinary gameList size";
		}
		else{
			
			//更新回DB
			Session updateSession = HibernateManager.txBegin();
			
			StringBuilder sBuilder = new StringBuilder();
			
			for(GameHallConfigModel model : gamelist){
				try {
					updateSession.update(model);
				} catch (Exception e) {
					sBuilder.append("update fail, OsType:"+model.getOsType()+", gameType:"+model.getGameType()+"(orderNum="+model.getOrderNum()+")");
				}
			}
			
			HibernateManager.txCommitFailRollbackClearSession();
			
			return sBuilder.toString();//如果成功的話，應該內容是""	
			
		}
	}
	
}
